package com.bestcem.xm.member.grpc.client;

import cn.hutool.core.util.StrUtil;
import com.bestcem.bp.grpc.v1.base.Page;
import com.bestcem.bp.xm.user.grpc.v1.services.*;
import com.bestcem.xm.common.core.constant.GrpcClientNames;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.label.constant.Constants;
import com.bestcem.xm.member.service.dto.GroupDTO;
import com.bestcem.xm.user.grpc.v1.common.IdRelation;
import io.grpc.StatusRuntimeException;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ming.xue <ming.xue@idiaoyan.com>
 * @desc 用户客户端
 * @date 2021-07-19
 */
@Slf4j
@Component("userClient")
public class UserClient {

    @GrpcClient(GrpcClientNames.DS_USER)
    private OrgServiceGrpc.OrgServiceBlockingStub orgServiceBlockingStub;

    @GrpcClient(GrpcClientNames.DS_USER)
    private UserGroupServiceGrpc.UserGroupServiceBlockingStub userGroupServiceBlockingStub;

    @GrpcClient(GrpcClientNames.DS_USER)
    private UserServiceGrpc.UserServiceBlockingStub userServiceBlockingStub;

    public ServiceResult<List<String>> listOrgIds(List<String> packageIds) {
        if (CollectionUtils.isEmpty(packageIds)) {
            return ServiceResult.success(Collections.emptyList());
        }
        ListOrgIdsByPackageIdsRequest request = ListOrgIdsByPackageIdsRequest.newBuilder().addAllPackageIds(packageIds).build();
        ListOrgIdsByPackageIdsResponse response;
        try {
            response = orgServiceBlockingStub.listOrgIdsByPackageIds(request);
        } catch (StatusRuntimeException e) {
            log.error("【联系人】根据package_ids查询租户ids失败, request: {}", request, e);
            return ServiceResult.fail("【联系人】根据package_ids查询租户ids失败");
        }
        if (response.getStatus().getCodeValue() != Constants.SUCCESS) {
            log.error("【联系人】根据package_ids查询租户ids失败, request: {}, response: {}", request, response);
            return ServiceResult.fail("【联系人】根据package_ids查询租户ids失败");
        }
        if (log.isInfoEnabled()) {
            log.info("【联系人】根据package_ids查询租户ids 结果总数: {}", response.getIdsList().size());
        }
        // 注:这里要使用可变的List
        return ServiceResult.success(new ArrayList<>(response.getIdsList()));
    }

    /**
     * 获取单个激活的Group
     *
     * @param id id
     * @return Group
     */
    public GroupDTO getGroup(String id) {
        GetGroupRequest request = GetGroupRequest.newBuilder()
                .setId(id)
                .build();
        GetGroupResponse response;
        try {
            response = userGroupServiceBlockingStub.getGroup(request);
        } catch (StatusRuntimeException e) {
            log.error("【联系人】获取单个Group失败，request:{}", request, e);
            return null;
        }
        if (response.getStatus().getCodeValue() != Constants.SUCCESS) {
            log.error("【联系人】获取单个Group失败，response:{}", response);
            return null;
        }
        return toGroupDTO(response.getGroup());
    }

    private GroupDTO toGroupDTO(Group group) {
        if (Objects.isNull(group)) {
            return null;
        }
        GroupDTO groupDTO = new GroupDTO();
        groupDTO.setId(group.getId());
        groupDTO.setAncestors(group.getParentIdsList());
        groupDTO.setParentId(group.getParentId());
        groupDTO.setRootId(group.getRootId());
        groupDTO.setIsRoot(group.getRoot());
        groupDTO.setOrgId(group.getOrgId());
        groupDTO.setCode(group.getCode());
        groupDTO.setSeq(group.getSeq());
        groupDTO.setTitle(group.getName());
        groupDTO.setGroupType(group.getType().getNumber());
        groupDTO.setGroupLevelId(group.getLevelId());
        groupDTO.setStatus(group.getStatus().getNumber());
        groupDTO.setContact(group.getPhone());
        groupDTO.setEmail(group.getEmail());
        groupDTO.setAdminId(group.getAdminId());
        groupDTO.setAdminName(group.getAdminName());
        return groupDTO;
    }

    public Organization getOrganization(String orgId) {
        GetOrgByIdOrCodeRequest.Builder builder = GetOrgByIdOrCodeRequest.newBuilder();
        if (StrUtil.isNotEmpty(orgId)) {
            builder.setId(orgId);
        }
        GetOrgByIdOrCodeRequest request = builder.build();

        GetOrgByIdOrCodeResponse response;
        try {
            response = orgServiceBlockingStub.getOrgByIdOrCode(request);
        } catch (StatusRuntimeException e) {
            log.error("【user】通过org_id获取org失败, request:{}", request, e);
            return null;
        }
        if (response.getStatus().getCodeValue() != Constants.SUCCESS) {
            log.error("【user】通过org_id获取org失败，response:{}", response);
            return null;
        }
        return response.getOrg();
    }

    public User getUser(String userId) {
        GetUserByIdRequest.Builder builder = GetUserByIdRequest.newBuilder().setId(userId);
        GetUserByIdResponse userResponse = userServiceBlockingStub.getUserById(builder.build());
        if (Constants.SUCCESS == userResponse.getStatus().getCodeValue()) {
            return userResponse.getUser();
        }
        log.error("查询用户信息异常：{}", userResponse.getStatus().getMessage());
        return null;
    }

    public Map<String, String> listGroupMap(String orgId, List<Integer> statusList) {
        List<Group> rows = listGroups(orgId, statusList);
        return rows.stream().collect(Collectors.toMap(Group::getId, Group::getName));
    }

    private List<Group> listGroups(String orgId, List<Integer> statusList) {
        Page pageParam = Page.newBuilder().setPage(1).setSize(10000).build();
        GroupCondition groupCondition = GroupCondition.newBuilder().setOrgId(orgId).build();
        ListGroupsRequest request = ListGroupsRequest.newBuilder()
                .setGroup(groupCondition)
                .setPage(pageParam)
                .addAllStatusesValue(statusList).build();
        ListGroupsResponse response;
        try {
            response = userGroupServiceBlockingStub.listGroups(request);
        } catch (StatusRuntimeException e) {
            log.error("【联系人】搜索用户组列表失败, request: {}", request, e);
            throw new RuntimeException("【联系人】搜索用户组列表失败, request: " + request);
        }
        if (response.getStatus().getCodeValue() != Constants.SUCCESS) {
            log.error("【联系人】搜索用户组列表失败, request: {}, response: {}", request, response);
            throw new RuntimeException("【联系人】搜索用户组列表失败, request: " + request);
        }
        return response.getGroupsList();
    }

    public Map<String, String> listGroupIdMaps(String orgSrcId, String orgDstId) {
        ListSampleGroupIdsRequest request = ListSampleGroupIdsRequest.newBuilder()
                .setSrcOrgId(orgSrcId)
                .setDstOrgId(orgDstId).build();
        ListSampleGroupIdsResponse response;
        try {
            response = userGroupServiceBlockingStub.listSampleGroupIds(request);
        } catch (StatusRuntimeException e) {
            log.error("【联系人】获取旧新组织层级id map失败, request: {}", request, e);
            return Collections.emptyMap();
        }
        if (response.getStatus().getCodeValue() != Constants.SUCCESS) {
            log.error("【联系人】获取旧新组织层级id map失败, request: {}, response: {}", request, response);
            return Collections.emptyMap();
        }
        List<IdRelation> list = response.getIdRelationsList();
        if (CollectionUtils.isEmpty(list)) {
            return Collections.emptyMap();
        }
        return list.stream().collect(Collectors.toMap(IdRelation::getOldId, IdRelation::getNewId));
    }
}
